<template>
  <!-- 签约分类弹窗 -->
  <el-dialog
    v-model="visible"
    :show-close="false"
    :append-to-body="true"
    :close-on-click-modal="false"
    top="10vh"
    width="70%"
    class="signing-categiries-pop component-shop-process-category header-no-padding"
    @close="closePopup"
  >
    <div class="signing-categiries-content">
      <!-- 标题 -->
      <div class="title">
        <div class="text">
          <span class="stress">*</span>{{ $t('shopProcess.addSigningCategory') }}
        </div>
        <div class="tips">
          {{ $t('shopProcess.signingCategoryTips') }}，
          <span v-if="isFirst">
            {{ $t('shopProcess.preSigned') }}
            <span class="bold">{{ signingCount }}</span>
            {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}，
          </span>
          {{ $t('shopProcess.chosen') }}
          <span class="bold">{{ signCategories.length }}</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}，
          {{ $t('shopProcess.mostAdd') }}
          <span class="bold">200</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}
        </div>
        <div
          class="close-btn"
          @click="closePopup"
        >
          <el-icon><Close /></el-icon>
        </div>
      </div>

      <!-- 内容 -->
      <div class="content">
        <div class="left-box">
          <div class="search-box">
            <input
              v-model="categoryName"
              class="search-input"
              clearable
              :placeholder="$t('publics.categoryInputTips')"
            >
          </div>
          <div
            v-loading="loading"
            element-loading-text="数据处理中..."
          >
            <el-tree-v2
              ref="categoryTreeRef"
              :data="categoryTreeData"
              :filter-method="filterNode"
              :props="categoryListTreeProps"
              class="filter-tree"
              show-checkbox
              highlight-current
              icon-class="el-icon-arrow-right"
              :default-checked-keys="signCategories.map(el=> el.categoryId)"
              :height="522"
              @check="onCheckChange"
              @node-click="handleNodeClick"
            >
              <template #default="{ node, data }">
                <el-tooltip
                  :content="data.grade === 2 ? data.categoryName + ' ' + data.deductionRate + '%' : data.categoryName"
                  placement="right"
                  effect="light"
                  :show-after="200"
                  class="custom-tree-node"
                >
                  <div
                    class="item-bar"
                  >
                    <div
                      v-rich="filterKey(data, categoryName, node)"
                      class="label"
                    />
                    <div
                      v-if="data.grade === 2"
                      class="unit"
                    >
                      {{ ' ' + data.deductionRate + '%' }}
                    </div>
                  </div>
                </el-tooltip>
              </template>
            </el-tree-v2>
          </div>
        </div>

        <!-- 右边表格 -->
        <div
          ref="tableBoxRef"
          class="right-boxs table-box prods-select-body"
        >
          <el-table
            :data="signCategories"
            height="574"
            :header-cell-style="{height:'50px',background:'#F5F5F5',color:'#000','font-weight': '400'}"
          >
            <el-table-column
              prop="categoryName"
              :label="$t('shopProcess.categoryName')"
            />
            <el-table-column
              prop="parentName"
              :label="$t('shopProcess.parentCategoryName')"
            />
            <el-table-column
              prop="platformRate"
              :label="$t('shopProcess.categoryRate')"
            >
              <template #default="{ row }">
                <span v-if="row.platformRate || row.platformRate === 0">{{ row.platformRate }} %</span>
                <span v-else>--</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="qualifications"
              :label="$t('shopProcess.categoryQualifications')"
              width="250px"
            >
              <template #default="scope">
                <div
                  :key="scope.row.qualifications"
                  class="business-qual"
                >
                  <imgs-upload
                    v-model="scope.row.qualifications"
                    :limit="2"
                    :prompt="false"
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column
              prop="address"
              :label="$t('sys.operation')"
              align="center"
            >
              <template #default="scope">
                <div
                  class="default-btn text-btn"
                  @click="deleteSelectedCategory(scope)"
                >
                  {{ $t('text.delBtn') }}
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <div class="btn-row foot-btn">
        <div
          class="default-btn"
          @click="closePopup"
        >
          {{ $t('homes.no') }}
        </div>
        <div
          class="default-btn primary-btn"
          @click="confirmSubmit"
        >
          {{ $t('homes.yes') }}
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { treeDataTranslate } from '@/utils'
import { Debounce } from '@/utils/debounce'
import { ElMessage } from 'element-plus'

// 树形是否初始化完成
let isInitialize = false
let changeValList = []
const filterKey = (data, key, node) => {
  // 获取结点分类名称
  const categoryName = data.categoryName
  if (!isInitialize) {
    // 初始化时默认显示已经勾选的结点，下面代码会影响默认展开的值，因为在第一次初始化时直接返回名称
    return `<span>${categoryName}</span>`
  }
  // 使用changeValList记录已经被标记的node, 避免被多次记录，从而导致鼠标移入移出会自动关闭展开的树节点
  if (!changeValList.some(item => item === node.id)) {
    if (!node.markIsExpanded) {
      // 如果当前结点没有被标记为展开
      node.expanded = false
      changeValList.push(node.id)
    }
  } else {
    if (isChangeVal) {
      changeValList = []
      isChangeVal = false
    }
  }
  const ind = categoryName.indexOf(key)
  if (ind !== -1 && key !== '') {
    // 当前结点匹配到关键词
    if (!node.markIsExpanded) {
      if (node.parent && !node.parent.markIsExpanded) {
        node.parent.expanded = true
        node.parent.markIsExpanded = true
        if (node.parent.parent && !node.parent.parent.markIsExpanded) {
          node.parent.parent.expanded = true
          node.parent.parent.markIsExpanded = true
        }
      }
    }
    // 高亮关键词
    return (
      categoryName.split('').slice(0, ind).join('') + "<span style='color: coral'>" + key + '</span>' + categoryName.split('').slice(ind + key.length).join('')
    )
  } else {
    // 当前结点没有匹配到关键词或者用户输入为空时，直接返回名称
    return `<span>${categoryName}</span>`
  }
}

const props = defineProps({
  // 签约分类列表
  signCategoryList: {
    type: Array,
    default () {
      return []
    }
  },
  /**
   * 是否从店铺信息申请签约
   * applyForSign=true时，请求可以签约的平台分类列表（已经签约的平台分类不会返回）
   */
  applyForSign: {
    type: Boolean,
    default: false
  },
  // 平台端是否开启了签约类目审核
  signAuditSwitch: {
    type: Boolean,
    default: false
  },
  signingCount: {
    type: Number,
    default: 0
  },
  isCreate: {
    type: Boolean,
    default: false
  },
  isFirst: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['closePopup'])

// 搜索参数
const categoryName = ref('')
const categoryTreeData = ref([])
const categoryListTreeProps = reactive({
  value: 'categoryId',
  label: 'categoryName'
})

const loading = ref(false)

const categoryTreeRef = ref(null)
let isChangeVal = false
watch(() => categoryName.value, (val) => {
  isChangeVal = true
  categoryTreeRef.value?.filter(val)
})

const visible = ref(false)
const init = () => {
  visible.value = true
  getPlatformCategory()
  getSignCategoryList()
}

// table渲染列表(可滚动)
const signCategories = ref([])
/**
 * 已签约类目列表
 */
const getSignCategoryList = () => {
  for (const el of props.signCategoryList) {
    signCategories.value.push({
      categoryId: el.categoryId,
      categoryName: el.name,
      parentId: el.parentId,
      parentName: el.parentName,
      platformRate: el.platformRate,
      customizeRate: el.customizeRate,
      qualifications: el.qualifications,
      categoryStatus: el.categoryStatus,
      categoryShopId: el.categoryShopId
    })
  }
}

/**
 * 搜索结点，该方法只起标记作用，
 */
// eslint-disable-next-line no-unused-vars
const filterNode = (value, node) => {
  isInitialize = true
  node.markIsExpanded = false
  return node.categoryName?.includes(value)
}

let allCategories = []
/**
 * 获取平台分类列表，并转换成树形结构
 */
const getPlatformCategory = () => {
  loading.value = true
  const url = props.applyForSign ? '/shop/signingAuditing/listApplySigningCategory' : '/prod/category/platformCategory'
  http({
    url: http.adornUrl(url),
    method: 'get',
    params: http.adornParams({
      maxGrade: 2,
      status: 1
    })
  }).then(({ data }) => {
    loading.value = false
    allCategories = data
    let categoryTreeDataPar = treeDataTranslate(data, 'categoryId', 'parentId')
    // 过滤没有下级分类的类目
    categoryTreeDataPar = removeNotThirdCategoryItem(categoryTreeDataPar)
    categoryTreeData.value = categoryTreeDataPar

    // 已选的二级分类父级id
    const secCategoryParentId = [...new Set(props.signCategoryList.map((item) => item.parentId))]
    // 所有一级、二级分类的父级id
    const expandCategoryIds = secCategoryParentId.concat(secCategoryParentId.map((item) => allCategories.find((el) => el.categoryId === item).parentId))
    nextTick(() => {
      // 设置已选的类目为展开状态
      categoryTreeRef.value?.setExpandedKeys(expandCategoryIds)
    })
  })
}

/**
 * 去除没有下级分类的类目
 */
const removeNotThirdCategoryItem = (treeData) => {
  const firstCategory = treeData
  const length = firstCategory.length
  for (let i = 0, index = 0; i < length; i++) {
    if (firstCategory[index].grade !== 2) {
      if (firstCategory[index].children && firstCategory[index].children.length > 0 && (firstCategory[index].children.some(item => item.children) || firstCategory[index].grade !== 0)) {
        const secondCategory = firstCategory[index].children
        firstCategory[index].children = removeNotThirdCategoryItem(secondCategory)
      } else {
        firstCategory.splice(index, 1)
        // 当前位置的元素已经被删除，当前位置索引不用++
        continue
      }
    }
    index++
  }
  return firstCategory
}

/**
 * 复选框勾选事件
 * @param {Object} nodeObj 当前勾选的节点数据
 * @param {Object} treeNodeInfo 整棵树的节点数据信息
 */
const onCheckChange = (nodeObj, treeNodeInfo) => {
  const tempList = treeNodeInfo.checkedNodes.filter(el => el.grade === 2)
  const tempIdList = tempList.map(el => el.categoryId)
  const isCheck = treeNodeInfo.checkedKeys.includes(nodeObj.categoryId)
  if (isCheck) {
    for (let i = tempList.length - 1; i >= 0; i--) {
      const el = tempList[i]
      if (!signCategories.value.map(item => item.categoryId).includes(el.categoryId)) {
        signCategories.value.push({
          categoryId: el.categoryId,
          categoryName: el.categoryName,
          parentName: el.parentName || allCategories.find(item => item.categoryId === el.parentId).categoryName,
          platformRate: el.deductionRate,
          categoryStatus: el.status,
          qualifications: ''
        })
      }
    }
  } else {
    for (let i = signCategories.value.length - 1; i >= 0; i--) {
      if (!tempIdList.includes(signCategories.value[i].categoryId)) {
        signCategories.value.splice(i, 1)
      }
    }
  }
}

/**
 * 删除已选分类
 */
const deleteSelectedCategory = (scope) => {
  categoryTreeRef.value.setChecked(scope.row.categoryId, false)
  signCategories.value.splice(scope.$index, 1)
}

/**
 * 确认
 */
const confirmSubmit = Debounce(() => {
  if (props.signingCount + signCategories.value.length > 200) {
    ElMessage({
      message: $t('shopProcess.categoryAddMaxLimitTips'),
      type: 'error',
      duration: 1000
    })
    return
  }
  if (signCategories.value.length > 0) {
    signCategories.value.forEach((el) => {
      signCategories.value.forEach((item) => {
        if (el.categoryId === item.categoryId) {
          el.qualifications = item.qualifications
        }
      })
    })
    signCategory()
  } else {
    ElMessage({
      message: $t('shopProcess.categorySigningNotEmpty'),
      type: 'error',
      duration: 1000
    })
  }
}, 1500)

let submit = false
/**
 * 请求签约分类
 */
const signCategory = () => {
  if (submit) {
    return
  }
  submit = true
  const params = []
  signCategories.value.forEach(item => {
    const param = {
      categoryId: item.categoryId,
      rate: item.platformRate,
      qualifications: item.qualifications ? item.qualifications : null
    }
    params.push(param)
  })
  let url
  if (props.applyForSign) {
    url = props.signAuditSwitch ? '/shop/signingAuditing/applyCategory' : '/shop/signingAuditing/addSigningCategory'
  } else {
    url = '/prod/category/signing'
  }
  http({
    url: http.adornUrl(url),
    method: 'post',
    data: params
  }).then(() => {
    ElMessage({
      message: props.applyForSign ? $t('shopProcess.categoryAddSuccess') : $t('shopProcess.categorySaveSuccess'),
      type: 'success',
      duration: 1000
    })
    closePopup()
  }).finally(() => {
    submit = false
  })
}

/**
 * 关闭弹窗
 */
const closePopup = () => {
  emit('closePopup', 'category')
}

const handleNodeClick = (nodeObj) => {
  if (nodeObj.grade !== 2) return
  const isChecked = categoryTreeRef.value.getCheckedKeys().includes(nodeObj.categoryId)
  categoryTreeRef.value.setChecked(nodeObj.categoryId, !isChecked)
  if (isChecked) {
    signCategories.value = signCategories.value.filter(item => item.categoryId !== nodeObj.categoryId)
  } else {
    signCategories.value.push({
      categoryId: nodeObj.categoryId,
      categoryName: nodeObj.categoryName,
      parentName: nodeObj.parentName || allCategories.find(item => item.categoryId === nodeObj.parentId).categoryName,
      platformRate: nodeObj.deductionRate,
      categoryStatus: nodeObj.status,
      qualifications: ''
    })
    if (!nodeObj.parentName) {
      signCategory.parentName = allCategories.find(el => el.categoryId === nodeObj.parentId).categoryName
    }
  }
}

defineExpose({
  init
})

</script>

<style lang="scss" scoped>
@use "index";
</style>
